package com.bytz.modules.cms.c4c.sync;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.extra.spring.SpringUtil;
import com.bytz.common.exception.BytzBootException;
import com.bytz.common.util.RedisUtil;
import com.bytz.common.util.SpringContextUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Collection;
import java.util.stream.Collectors;

public class C4cBaseAuthRequestInterceptor implements RequestInterceptor {

    private static final String C4C_CSRF_TOKEN_KEY = "c4c:opportunity:token";

    private static final String C4C_COOKIE_KEY = "c4c:opportunity:cookie";

    @Value("${c4c-api.basic-auth-username}")
    private String username;

    @Value("${c4c-api.basic-auth-password}")
    private String password;

    private C4cOdataFeign c4cOdataFeign;

    private final RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

    @Override
    @SuppressWarnings("unchecked")
    public void apply(RequestTemplate requestTemplate) {
        if (c4cOdataFeign == null) {
            c4cOdataFeign = SpringContextUtils.getBean(C4cOdataFeign.class);
        }

        // 基础认证
        requestTemplate.header("Authorization", "Basic " + Base64Encoder.encode(username + ":" + password));

        // 当请求不为get时，向header中添加token和cookie
        if (!RequestMethod.GET.name().equals(requestTemplate.method())) {
            String token = (String) redisUtil.get(C4C_CSRF_TOKEN_KEY);
            String cookie = (String) redisUtil.get(C4C_COOKIE_KEY);
            if (token == null || cookie == null) {
                Response res = c4cOdataFeign.getToken("Fetch");
                Collection<String> tokens = res.headers().get("x-csrf-token");
                Collection<String> cookies = res.headers().get("Set-Cookie");
                if (tokens == null || cookies == null) {
                    throw new BytzBootException("获取c4c token失败");
                }
                cookie = cookies.stream().map(each -> each.split(";")[0]).collect(Collectors.joining("; "));
                token = tokens.stream().findFirst().orElseThrow(() -> new BytzBootException("获取c4c token失败"));
                // 十分钟内可以复用token、cookie
                redisUtil.set(C4C_CSRF_TOKEN_KEY, token, 600);
                redisUtil.set(C4C_COOKIE_KEY, cookie, 600);
            }
            requestTemplate.header("Cookie", cookie);
            requestTemplate.header("x-csrf-token", token);
        }
    }
}
